import asyncio
import logging
from datetime import datetime, date
from sqlalchemy import select
from config.database import async_engine
from module_kylin.entity.do.future_settlement_do import KylinFutureSettlement
from module_kylin.service.future_settlement_service import FutureSettlementService
from module_kylin.entity.vo.future_settlement_vo import (
    ImportSettlementToDailyModel,
)

# 配置日志
logger = logging.getLogger(__name__)


async def import_future_settlement_daily_task_sync():
    """
    异步方法，用于定时任务调度器调用
    直接执行异步导入任务，避免创建新的事件循环
    """
    try:
        await import_future_settlement_daily_task()
    except Exception as e:
        logger.error(f"定时导入期货结算单任务执行异常: {e}", exc_info=True)


async def import_future_settlement_daily_task():
    """
    定时导入期货结算单任务
    """
    try:
        logger.info("开始执行定时导入期货结算单任务")

        # 获取当前日期
        today = date.today()
        logger.info(f"导入日期: {today}")

        # 从config.database导入AsyncSessionLocal
        from config.database import AsyncSessionLocal
        from sqlalchemy import select, update
        from module_kylin.entity.do.future_settlement_do import KylinFutureSettlement
        
        # 使用异步会话查询待导入的结算单
        async with AsyncSessionLocal() as db:
            query = select(
                KylinFutureSettlement.id,
                KylinFutureSettlement.account_code,
                KylinFutureSettlement.settlement_date,
                KylinFutureSettlement.settlement_type,
                KylinFutureSettlement.profit_calc_type,
                KylinFutureSettlement.file_name,
                KylinFutureSettlement.settlement_status,
                KylinFutureSettlement.create_time,
                KylinFutureSettlement.update_time,
            ).where(
                KylinFutureSettlement.settlement_status == "1",
                KylinFutureSettlement.settlement_type == "D",
            )
            result = await db.execute(query)
            # 获取映射结果
            settlement_mappings = result.mappings().all()

            logger.info(f"找到{len(settlement_mappings)}个待导入的结算单")
            total_count = len(settlement_mappings)
            success_count = 0
            failed_count = 0
            fail_records = []

            # 遍历所有待导入的结算单
            for settlement_data in settlement_mappings:
                try:
                    logger.info(f"当前结算单数据: {settlement_data}")
                    
                    # 创建导入模型（直接使用映射数据）
                    import_model = ImportSettlementToDailyModel(
                        id=settlement_data.id,
                        file_name=settlement_data.file_name,
                        account_code=settlement_data.account_code,
                        settlement_date=settlement_data.settlement_date,
                        settlement_type=settlement_data.settlement_type,
                        profit_calc_type=settlement_data.profit_calc_type,
                    )

                    # 直接使用当前异步会话执行导入操作
                    await FutureSettlementService.import_settlement_to_daily(db, import_model)
                    success_count += 1
                    logger.info(
                        f"成功导入结算单: 账户={settlement_data.account_code}, 日期={settlement_data.settlement_date}"
                    )
                    
                    # 更新结算单状态为已导入 - 注释掉这部分，因为import_settlement_to_daily方法内部已经处理了状态更新
                    # update_status_query = update(KylinFutureSettlement).where(
                    #     KylinFutureSettlement.id == settlement_data.id
                    # ).values(
                    #     settlement_status="2",  # 2:已入库
                    #     update_time=datetime.now()
                    # )
                    # await db.execute(update_status_query)
                    await db.commit()
                except Exception as e:
                    failed_count += 1
                    error_msg = f"导入失败 - 账户={settlement_data.account_code}, 日期={settlement_data.settlement_date}, 错误: {str(e)}"
                    fail_records.append(error_msg)
                    logger.error(error_msg, exc_info=True)
                    await db.rollback()

        # 记录执行结果
        logger.info(f"定时导入期货结算单任务执行完成")
        logger.info(f"总任务数: {total_count}")
        logger.info(f"成功数: {success_count}")
        logger.info(f"失败数: {failed_count}")

        if fail_records:
            logger.error(f"失败记录: {fail_records}")

    except Exception as e:
        logger.error(f"定时导入期货结算单任务执行异常: {str(e)}", exc_info=True)

    logger.info("定时导入期货结算单任务结束")